package post

import (
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"notabug.org/ropemann/imabon/src/database"
	"notabug.org/ropemann/imabon/src/entities/utils"
)

type Post struct {
	ID         *primitive.ObjectID `json:"ID" bson:"_id,omitempty"`
	AuthorId   int64               `json:"AuthorId" bson:"authorId,omitempty"`
	AuthorName string              `json:"AuthorName" bson:"authorName,omitempty"`
	Body       string              `json:"Body" bson:"body,omitempty"`
	Image      string              `json:"Image" bson:"image,omitempty"`
	CreatedAt  *primitive.DateTime `json:"CreatedAt" bson:"createdAt,omitempty"`
	UpdatedAt  *primitive.DateTime `json:"UpdatedAt" bson:"updatedAt,omitempty"`
}

func NewPost(authorName, body, image string) *Post {
	newId := primitive.NewObjectID()
	now := primitive.NewDateTimeFromTime(time.Now())

	post := Post{
		ID:         &newId,
		AuthorId:   utils.GenerateAuthorId(),
		AuthorName: authorName,
		Body:       body,
		Image:      image,
		CreatedAt:  &now,
		UpdatedAt:  &now,
	}
	return &post
}

func CreatePost(board, threadId string, post *Post) (int64, error) {
	db := database.NewMongoDBConn()
	db.Connect()
	defer db.Close()

	collection := db.Client.Database("threads").Collection(board)

	objId, _ := primitive.ObjectIDFromHex(threadId)
	update := bson.M{
		"$push":        bson.M{"posts": post},
		"$currentDate": bson.M{"updatedAt": true},
	}

	res, err := collection.UpdateOne(db.Ctx, bson.M{"_id": objId}, update)

	return res.ModifiedCount, err
}

func DeletePost(board, threadId, postId string) (int64, error) {
	db := database.NewMongoDBConn()
	db.Connect()
	defer db.Close()

	collection := db.Client.Database("threads").Collection(board)

	threadObjId, _ := primitive.ObjectIDFromHex(threadId)
	postObjId, _ := primitive.ObjectIDFromHex(postId)

	filter := bson.M{"_id": threadObjId}
	update := bson.M{
		"$pull": bson.M{
			"posts": bson.M{
				"_id": postObjId,
			},
		},
	}

	res, err := collection.UpdateOne(db.Ctx, filter, update)

	return res.ModifiedCount, err
}
